Skip to content

Merge extensions into core package as PEP 771 extras#1054

Open
seherv wants to merge 11 commits into
dapr:mainfrom
seherv:bundled-optional-exts
Open

Merge extensions into core package as PEP 771 extras#1054
seherv wants to merge 11 commits into
dapr:mainfrom
seherv:bundled-optional-exts

Conversation

@seherv

@seherv seherv commented May 26, 2026

Copy link
Copy Markdown
Contributor

Description

Moves all the dapr-ext* packages into the main dapr package, and exposes them as extras.

pip install dapr-ext-pkgname is now pip install "dapr[pkgname]".

IMPORTANT: this is a breaking change, unlike the dapr*-dev removal. All the old extension packages must be uninstalled manually before re-installing dapr. More info in dapr/__init__.py, README.md and RELEASE.md.

Issue reference

We strive to have all PR being opened based on an issue, where the problem or feature have been discussed prior to implementation.

Please reference the issue this PR will close: #1026

Checklist

Please make sure you've completed the relevant tasks for this PR, out of the following list:

  • Code compiles correctly
  • Created/updated tests
  • Extended the documentation

seherv added 2 commits May 26, 2026 09:45
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>
@codecov

codecov Bot commented May 26, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.92208% with 34 lines in your changes missing coverage. Please review.
✅ Project coverage is 81.90%. Comparing base (bffb749) to head (04a579e).
⚠️ Report is 143 commits behind head on main.

Files with missing lines Patch % Lines
dapr/__init__.py 81.81% 14 Missing ⚠️
dapr/ext/fastapi/__init__.py 42.85% 4 Missing ⚠️
dapr/ext/flask/__init__.py 42.85% 4 Missing ⚠️
dapr/ext/grpc/__init__.py 33.33% 4 Missing ⚠️
dapr/ext/langgraph/__init__.py 42.85% 4 Missing ⚠️
dapr/ext/strands/__init__.py 33.33% 4 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1054      +/-   ##
==========================================
- Coverage   86.63%   81.90%   -4.73%     
==========================================
  Files          84      116      +32     
  Lines        4473     9462    +4989     
==========================================
+ Hits         3875     7750    +3875     
- Misses        598     1712    +1114     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@JoshVanL JoshVanL requested a review from Copilot May 26, 2026 10:45

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@seherv seherv requested a review from Copilot May 27, 2026 08:27

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 121 out of 201 changed files in this pull request and generated 3 comments.

Comments suppressed due to low confidence (2)

pyproject.toml:1

  • The dependency was renamed from msgpack-python (legacy, last release 0.5.6, capped at <1.0.0 in the deleted ext/*/pyproject.toml) to msgpack with >=1.0,<2.0. These are distinct PyPI projects with different APIs — msgpack 1.x removed encoding=/use_bin_type defaults and changed Unpacker/packb keyword arguments. Confirm that dapr/ext/langgraph/dapr_checkpointer.py and dapr/ext/strands/dapr_session_manager.py actually use the msgpack (1.x) API and not the msgpack-python (0.x) API; otherwise serialization of existing checkpoints/sessions in production state stores will break silently on upgrade.
    flask_dapr/init.py:1
  • Importing actor and app as names from dapr.ext.flask only works if those submodules have already been bound as attributes of the parent package. dapr/ext/flask/__init__.py does from .actor import DaprActor / from .app import DaprApp, which sets the attributes as a side effect — but only when those imports succeed. If the optional flask dependency is missing, dapr.ext.flask.__init__ raises a new ImportError before binding actor/app, and this line will then raise ImportError: cannot import name 'actor' from 'dapr.ext.flask', masking the intended FutureWarning-then-helpful-error path. Consider importing the submodules explicitly (from dapr.ext.flask import actor, app on its own line, or import dapr.ext.flask.actor as actor) and/or wrapping in a try/except that surfaces the original cause.

Comment thread dapr/__init__.py
Comment thread .github/workflows/build-tag.yaml Outdated
Comment thread AGENTS.md
@seherv seherv requested a review from Copilot June 1, 2026 09:12

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 121 out of 201 changed files in this pull request and generated 2 comments.

Comments suppressed due to low confidence (1)

pyproject.toml:1

  • all = ["dapr[fastapi,...]"] is a self-referential dependency (the project depending on itself with extras). Some resolvers/installers may reject this or behave unexpectedly (circular/recursive requirement). Prefer making all the explicit union of third-party deps (duplicating the lists), or use a build-tool-supported mechanism to compose extras without introducing a Requires-Dist: dapr[...] entry.

Comment thread .github/workflows/build.yaml
Comment thread dapr/__init__.py
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>
@seherv seherv requested a review from Copilot June 1, 2026 13:20

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 122 out of 202 changed files in this pull request and generated 1 comment.

Comments suppressed due to low confidence (1)

pyproject.toml:1

  • all is declared as an extra that depends on the same project (dapr[...]). Self-referential extras can confuse resolvers and may lead to circular/duplicate requirements (especially when users run pip install "dapr[all]"). Prefer expanding all to the union of the third-party dependencies across the other extras (duplicate the dependency strings), so all is just a normal list of external requirements.

Comment thread dapr/__init__.py
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>
@seherv seherv marked this pull request as ready for review June 1, 2026 15:28
@seherv seherv requested review from a team as code owners June 1, 2026 15:28
@seherv seherv force-pushed the bundled-optional-exts branch from 4ac3c15 to 88cdef6 Compare June 1, 2026 15:31
seherv added 2 commits June 2, 2026 11:18
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>
# Conflicts:
#	dapr/ext/strands/AGENTS.md
Comment thread .github/workflows/build-tag.yaml
try:
from .actor import DaprActor
from .app import DaprApp
except ImportError as exc:

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is a local import, how can it raise ImportError? Also, if this code is correct, why do we raise ImportError for an optional dependency?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These import guards are one way to stop users who haven't installed the extras from trying to import the extras (which now live in the core repo). Python extras are not really a conditional build step like in compiled languages, they are just a set of optional dependencies but all the code ships in the core package anyway.

It wasn't necessary when we had the extension packages because the code was not even there if you didn't install them.

Maybe the import guards are too vague, I'll make them a bit more explicit

Comment thread dapr/ext/flask/actor.py Outdated
Comment thread tests/test_legacy_extension_check.py
seherv added 2 commits June 5, 2026 18:12
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>
acroca
acroca previously approved these changes Jun 8, 2026
Signed-off-by: Sergio Herrera <627709+seherv@users.noreply.github.com>

@sicoyle sicoyle left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

few comments/questions. Overall, I am on a call with Cassie right now, bc we're supposed to release 1.18 today... so all of your 1.XX refs need to bump by one pls bc this will not make the 1.18 release.

Comment thread dapr/ext/grpc/py.typed

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this file change correct?

Comment on lines +31 to +33
from ulid import ULID

from dapr.clients import DaprClient

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

are these used?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this file rename correct?


# Import your main classes here
from dapr.ext.langgraph.dapr_checkpointer import DaprCheckpointer
_LANGGRAPH_OPTIONAL_MODULES = frozenset({'msgpack', 'langchain_core', 'langgraph', 'ulid'})

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we have to do this kind of stuff now due to the new pkg setup? is this the only/best means of going about stuff like this so end users don't get the import issues on their end?

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why this rename?

Comment thread flask_dapr/__init__.py
Comment on lines +35 to +37
# Register submodule aliases so `from flask_dapr.actor import DaprActor` and
# `import flask_dapr.app` resolve without on-disk files.
sys.modules['flask_dapr.actor'] = actor

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do you do this on all of these pkgs we're changing?

Comment thread pyproject.toml
# Bundling the extensions into the core wheel brings their source under mypy's
# namespace walk for the first time. These modules carry pre-existing type
# errors that were previously hidden by the separate-workspace-package layout.
# Ignored here to keep this packaging PR scope-limited; clean up in a follow-up.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this just means linter/type issues that need fixing? can you create an issue for this pls and link

Comment thread RELEASE.md
Comment on lines +11 to +13
**The previously-separate distributions** — `dapr-ext-fastapi`, `dapr-ext-grpc`,
`dapr-ext-langgraph`, `dapr-ext-strands`, `dapr-ext-workflow`, `flask-dapr` —
are **no longer published**.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you say as of 1.18. These will still very much have to be updated for backporting fixes for 1.17 and 1.16

Comment thread RELEASE.md
Comment on lines +33 to +38
Existing installs must migrate explicitly:

```sh
pip uninstall -y dapr-ext-fastapi dapr-ext-grpc dapr-ext-langgraph dapr-ext-strands dapr-ext-workflow flask-dapr
pip install --force-reinstall --no-deps dapr
pip install "dapr[<extras>]"

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

so we need to call this out in discord as users will have to do this as of 1.18 with this change is that right?

Comment thread dapr/__init__.py
limitations under the License.
"""

# TODO: remove in 1.20 (pre-1.19 dapr-ext-* / flask-dapr migration only).

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you actually update this to be 1.21. I just got on a call with cassie that we are cutting 1.18 today so 1.18 will not get these changes. This will be in for 1.19 so all of your 1.20 refs need to be 1.21 pls and any other 1.19 refs become 1.20 pls

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Merge dapr-ext-* packages into the SDK as core/extras

4 participants